package pl.edu.agh.jemo.evolution.selections.impl;

import pl.edu.agh.jemo.evolution.specimen.Specimen;

/**
 * Utility class used by BinaryTournament.
 * Simple implementation of Binary Tree, where each node holds parent and two children reference.
 * Every node of tree is representation of one specimen. Instance of this class works as a single tree node, not the whole tree.
 * Different nodes of tree might contain the same specimen reference. Root node is the winner of all tournament. Every next level is previous stage, containing both winner and looser.
 * Specimen are compared using their fitness.
 * 
 * @author Jakub Dombrowski, Marcin Zbijowski
 *
 */
public class BinaryTournamentTree {
	/**
	 * References to other nodes of the tree, parent and two sons.
	 */
	private BinaryTournamentTree up, left, right;
	/**
	 * Specimen reference associated with that tree node.
	 */
	private Specimen specimen;

	/**
	 * Creates single tree node, not attached to any other node and not associated with any specimen.
	 */
	public BinaryTournamentTree() {
		this(null,null,null,null);
	}

	/**
	 * Creates tree node not attached to tree, but with specimen reference already assigned.
	 * 
	 * @param specimen Reference to specimen connected with that tree node.
	 */
	public BinaryTournamentTree(Specimen specimen) {
		this(null,null,null,specimen);
	}
	
	/**
	 * Creates tree node as a complete part of tree with specimen assigned.
	 * 
	 * @param up Reference to parent tree node.
	 * @param left Reference to one of the node sons.
	 * @param right Reference to another node son.
	 * @param spec Reference to specimen assigned with that tree node.
	 */
	public BinaryTournamentTree(BinaryTournamentTree up,
			BinaryTournamentTree left, BinaryTournamentTree right,
			Specimen spec) {
		this.up = up;
		this.right = right;
		this.left = left;
		this.specimen = spec;
	}

	/**
	 * Returns parent of tree node.
	 * 
	 * @return  Reference to binary tree node, being parent of tree node.
	 */
	public BinaryTournamentTree getUp() {
		return up;
	}

	/**
	 * Sets parent reference to attach node to tree.
	 * 
	 * @param up New node parent reference
	 */
	public void setUp(BinaryTournamentTree up) {
		this.up = up;
	}

	/**
	 * Returns one son of tree node.
	 * 
	 * @return  Reference to binary tree node, being left son of tree node.
	 */
	public BinaryTournamentTree getLeft() {
		return left;
	}

	/**
	 * Sets left son reference to attach node to tree.
	 * 
	 * @param left New node left son reference
	 */
	public void setLeft(BinaryTournamentTree left) {
		this.left = left;
	}

	/**
	 * Returns other son of tree node.
	 * 
	 * @return  Reference to binary tree node, being right son of tree node.
	 */
	public BinaryTournamentTree getRight() {
		return right;
	}

	/**
	 * Sets right son reference to attach node to tree.
	 * 
	 * @param right New node right son reference
	 */
	public void setRight(BinaryTournamentTree right) {
		this.right = right;
	}

	/**
	 * Returns specimen reference associated with this tree node.
	 * 
	 * @return Value of specimen reference stored int this node.
	 */
	public Specimen getSpecimen() {
		return specimen;
	}

	/**
	 * Associates this tree node with specimen reference.
	 * One specimem may be associated with more then one tree node.
	 * 
	 * @param specimen Specimen reference to be associated with tree node.
	 */
	public void setSpecimen(Specimen specimen) {
		this.specimen = specimen;
	}
}
